"""hexdumpy - Google wave robot that appends hex representation of blip
content in hex."""
from waveapi import events
from waveapi import model
from waveapi import robot
from waveapi import document

ROBOT = "hexdumpy"
ROBOT_ID = "hexdumpy@appspot.com"

def hexdump(src, length=8):
    """Return representation of src as hex"""
    n = 0
    result = ''
    while src:
        s, src = src[:length], src[length:]
        hexa = ' '.join(["%02X"%ord(x) for x in s])
        result += "%04X   %-*s\n" % (n, length*3, hexa)
        n += length
    return result
        
def on_participants_changed(properties, context):
    """Invoked when any participants have been added/removed."""
    added = properties['participantsAdded']
    for p in added:
        notify(context)

def on_robot_added(properties, context):
    """Invoked when the robot has been added."""
    root_wavelet = context.GetRootWavelet()
    root_wavelet.CreateBlip().GetDocument().SetText("Thank's for including me on this wave")
    
def on_blip_submitted(properties, context):
    """Invoked whenever a blip is submitted. 
    Note that this event only fires once the user clicks Done 
    or moves to another blip."""
    blip = context.GetBlipById(properties['blipId'])
    contents = blip.GetDocument().GetText()
    # Check if robot has previously been called for this blip   
    if ROBOT_ID in blip.GetContributors():
        '''At this point I would like to find the blip created by robot 
        and delete it using code similar to this:
        
        for cblip_id in blip.GetChildBlipIds():
            if context.GetBlipById(cblip_id).GetCreator() == ROBOT_ID:
                cblip_id.Delete()
                
        Currently the API does not return child blip instances, so must assume
        that any inlibe blips were created by the robot and delete them. Not the 
        best solution but a starting point.'''
        for cblip_id in blip.GetChildBlipIds():
            blip.GetDocument().DeleteInlineBlip(cblip_id)
            
    hex_blip = blip.GetDocument().AppendInlineBlip()
    hex_dump = hexdump(contents)
    doc = hex_blip.GetDocument()
    doc.SetText(hex_dump)
    # set non proportional bold font
    r = document.Range(0, len(hex_dump)-1)
    doc.SetAnnotation(r, 'style/fontFamily', 'courier new,monospace')
    doc.SetAnnotation(r, 'style/fontWeight', 'bold')

def notify(context):
    """Set text in blip for root wavelet"""
    root_wavelet = context.GetRootWavelet()
    root_wavelet.CreateBlip().GetDocument().SetText("This wave's blips will include a hex representation because of me.")
    
def trace(msg, context):
    """Output trace info to blip"""
    root_wavelet = context.GetRootWavelet()
    root_wavelet.CreateBlip().GetDocument().SetText("hexdumpy trace: %s" % msg)

if __name__ == '__main__':
    hex_robot = robot.Robot('hexdumpy', 
        image_url='http://hexdumpy.appspot.com/assets/icon.png',
        version='1',
        profile_url='http://hexdumpy.appspot.com/')
    hex_robot.RegisterHandler(events.WAVELET_PARTICIPANTS_CHANGED, on_participants_changed)
    hex_robot.RegisterHandler(events.WAVELET_SELF_ADDED, on_robot_added)
    hex_robot.RegisterHandler(events.BLIP_SUBMITTED, on_blip_submitted)
    hex_robot.Run(debug=True)
